package com.markerhub.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.markerhub.common.dto.PassDto;
import com.markerhub.common.lang.Const;
import com.markerhub.common.lang.Result;
import com.markerhub.entity.SysRole;
import com.markerhub.entity.SysUser;
import com.markerhub.entity.SysUserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 用户管理Controller
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/api/sys-user")
public class SysUserController extends BaseController {

	// 不再需要密码编码器，密码以明文方式存储

	/**
	 * 获取用户详情
	 * @param id 用户ID
	 * @return 用户信息
	 */
	@ApiOperation(value = "获取用户详情", notes = "根据用户ID获取用户详细信息")
	@GetMapping("/detail/{id}")
	@PreAuthorize("hasAuthority('sys:user:list')")
	public Result detail(@PathVariable("id") Long id) {

		SysUser sysUser = sysUserService.getById(id);
		Assert.notNull(sysUser, "找不到该用户");

		List<SysRole> roles = sysRoleService.listRolesByUserId(id);

		sysUser.setSys_roles(roles);
		return Result.succ(200, "获取用户信息成功", sysUser);
	}

	/**
	 * 获取用户列表
	 * @param username 用户名搜索
	 * @return 用户分页列表
	 */
	@ApiOperation(value = "获取用户列表", notes = "获取用户分页列表，支持用户名搜索")
	@GetMapping("/list")
	@PreAuthorize("hasAuthority('sys:user:list')")
	public Result list(String username) {

		Page<SysUser> pageData = sysUserService.page(getPage(), new QueryWrapper<SysUser>()
				.like(StrUtil.isNotBlank(username), "username", username));

		pageData.getRecords().forEach(u -> {
			u.setSys_roles(sysRoleService.listRolesByUserId(u.getId()));
		});

		return Result.succ(200, "获取用户分页列表成功", pageData);
	}

	/**
	 * 查询用户（与list类似，保持兼容性）
	 * @param username 用户名搜索
	 * @return 用户分页列表
	 */
	@ApiOperation(value = "查询用户", notes = "查询用户，支持用户名搜索和ID查询")
	@GetMapping("/query")
	@PreAuthorize("hasAuthority('sys:user:query')")
	public Result query(String username, Long id) {
		// 如果提供了id参数，优先根据id查询用户
		if (id != null) {
			SysUser user = sysUserService.getById(id);
			if (user != null) {
				// 包装为分页数据格式，保持与前端期望一致
				Page<SysUser> page = new Page<>();
				page.setRecords(Collections.singletonList(user));
				page.setTotal(1L);
				return Result.succ(page);
			}
			// 用户不存在，返回空数据
			return Result.succ(new Page<>());
		}
		// 如果没有提供id，则按原逻辑根据用户名查询
		return list(username);
	}

	/**
	 * 新增用户
	 * @param sysUser 用户信息
	 * @return 创建结果
	 */
	@ApiOperation(value = "新增用户", notes = "创建新用户")
	@PostMapping("/add")
	@PreAuthorize("hasAuthority('sys:user:add')")
	public Result add(@Validated @RequestBody SysUser sysUser) {

		sysUser.setCreated(LocalDateTime.now());
//		sysUser.setStatus(Const.STATUS_ON);

		// 默认密码，直接使用明文
		sysUser.setPassword(Const.DEFULT_PASSWORD);

		// 默认头像
		sysUser.setAvatar(Const.DEFULT_AVATAR);

		sysUserService.save(sysUser);
		return Result.succ(200, "创建用户成功", sysUser);
	}

	/**
	 * 更新用户
	 * @param sysUser 用户信息
	 * @return 更新结果
	 */
	@ApiOperation(value = "更新用户", notes = "更新用户信息")
	@PutMapping("/update")
	@PreAuthorize("hasAuthority('sys:user:update')")
	public Result update(@Validated @RequestBody SysUser sysUser) {

		sysUser.setUpdated(LocalDateTime.now());

		sysUserService.updateById(sysUser);
		return Result.succ(200, "更新用户成功", sysUser);
	}

	/**
	 * 删除单个用户
	 * @param id 用户ID
	 * @return 删除结果
	 */
	@ApiOperation(value = "删除单个用户", notes = "根据用户ID删除用户")
	@DeleteMapping("/delete/{id}")
	@PreAuthorize("hasAuthority('sys:user:delete')")
	public Result deleteById(@PathVariable("id") Long id) {
		return delete(new Long[]{id});
	}

	/**
	 * 批量删除用户
	 * @param ids 用户ID数组
	 * @return 删除结果
	 */
	@ApiOperation(value = "批量删除用户", notes = "批量删除多个用户")
	@Transactional
	@DeleteMapping("/delete")
	@PreAuthorize("hasAuthority('sys:user:delete')")
	public Result delete(@RequestBody Long[] ids) {

		sysUserService.removeByIds(Arrays.asList(ids));
		sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id", ids));

		return Result.succ(200, "删除用户成功", null);
	}

	/**
	 * 分配角色
	 * @param data 包含userId和roleIds的对象
	 * @return 分配结果
	 */
	@ApiOperation(value = "分配角色", notes = "为用户分配角色")
	@Transactional
	@PutMapping("/role")
	@PreAuthorize("hasAuthority('sys:user:role')")
	public Result role(@RequestBody UserRoleAssignDto data) {
		return rolePerm(data.getUserId(), data.getRoleIds());
	}

	// 内部方法，用于处理角色分配逻辑
	private Result rolePerm(Long userId, Long[] roleIds) {

		List<SysUserRole> userRoles = new ArrayList<>();

		Arrays.stream(roleIds).forEach(r -> {
			SysUserRole sysUserRole = new SysUserRole();
			sysUserRole.setRole_id(r);
			sysUserRole.setUser_id(userId);

			userRoles.add(sysUserRole);
		});

		sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
		sysUserRoleService.saveBatch(userRoles);

		// 删除缓存
		SysUser sysUser = sysUserService.getById(userId);
		sysUserService.clearUserAuthorityInfo(sysUser.getUsername());

		return Result.succ(200, "分配角色成功", null);
	}

	/**
	 * 重置密码
	 * @param data 包含userId的对象
	 * @return 重置结果
	 */
	@ApiOperation(value = "重置密码", notes = "重置用户密码为默认密码")
	@PutMapping("/repass")
	@PreAuthorize("hasAuthority('sys:user:repass')")
	public Result repass(@RequestBody PassResetDto data) {

		SysUser sysUser = sysUserService.getById(data.getUserId());

		sysUser.setPassword(Const.DEFULT_PASSWORD);
		sysUser.setUpdated(LocalDateTime.now());

		sysUserService.updateById(sysUser);
		return Result.succ(200, "重置密码成功", null);
	}

	/**
	 * 更新个人密码
	 * @param passDto 密码信息
	 * @param principal 当前用户
	 * @return 更新结果
	 */
	@ApiOperation(value = "更新个人密码", notes = "当前用户更新自己的密码")
	@PostMapping("/updatePass")
	public Result updatePass(@Validated @RequestBody PassDto passDto, Principal principal) {

		SysUser sysUser = sysUserService.getByUsername(principal.getName());

		// 直接比较明文密码
		if (!passDto.getCurrentPass().equals(sysUser.getPassword())) {
			return Result.fail("旧密码不正确");
		}

		// 直接使用明文密码
		sysUser.setPassword(passDto.getPassword());
		sysUser.setUpdated(LocalDateTime.now());

		sysUserService.updateById(sysUser);
		return Result.succ(200, "更新密码成功", null);
	}

	// 辅助DTO类
	public static class UserRoleAssignDto {
		private Long userId;
		private Long[] roleIds;

		public Long getUserId() {
			return userId;
		}

		public void setUserId(Long userId) {
			this.userId = userId;
		}

		public Long[] getRoleIds() {
			return roleIds;
		}

		public void setRoleIds(Long[] roleIds) {
			this.roleIds = roleIds;
		}
	}

	public static class PassResetDto {
		private Long userId;

		public Long getUserId() {
			return userId;
		}

		public void setUserId(Long userId) {
			this.userId = userId;
		}
	}
}
